package educar.models;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Date;

import educar.db.JPA;

public class Teacher {
	
	private String nro_docente;
	private String dni; 
	private String nombre;
	private String apellido;
	private String direccion;
	private User user;
	private String sexo;
	private String telefono;
	private String email;
	private String fecha_nac;
	private int edad;
	private static JPA jpa = new JPA();
	
	
	/**
	 * Constructor de la clase docente
	 * @param newDni "string que contiene el dni"
	 * @param newNombre "string que contiene el nombre"
	 * @param newApellido "string que contiene el apellido"
	 * @param newUser "string que contiene el usuario asosiado al maestro"
	 * @param newSexo "sexo del docente  string 'male' or 'female' "
	 * @param newDireccion "direccion del docente string"
	 * @param newTelefono "telefono del docente en string"
	 * @param newEmail "string con el email del docente"
	 * @param newFecha_nac "string con la fecha de nacimiento 'yyyy-MM-dd' formato"
	 */
	public Teacher(String newNumber,String newDni,String newNombre,String newApellido,User newUser,String newSexo,
											String newDireccion,String newTelefono,String newEmail,String newFecha_nac) {
		setNro_docente(newNumber);
		setDni(newDni);
		setNombre(newNombre);
		setApellido(newApellido);
		setUser(newUser);
		setDireccion(newDireccion);
		setTelefono(newTelefono);
		setEmail(newEmail);
		setFecha_nac(newFecha_nac);
		setEdad(edad(newFecha_nac));
		setSexo(newSexo);
	}
	
	/**
	 * Retorna el numero de docente
	 * @return  "el nuemro de docente"
	 */
	public String getNumero_docente() {
		return nro_docente;
	}
	
	/**
	 * permite establecer el numero de docente
	 * @param newNumero "int con el numero"
	 */
	public void setNro_docente(String newNumero) {
		nro_docente = newNumero;
	}
	
	/**
	 * Establece el dni del docente
	 * @param newDNI "dni en tipo string" 
	 */
	public void setDni(String newDNI){
		dni = newDNI;
	}
	
	/**
	 * obtiene el dni del docente
	 * @return string con el dni
	 */
	public String getDni(){
		return dni;
	}
	
	/**
	 * establece el nombre del docente
	 * @param newNombre "string con el nombre"
	 */
	public void setNombre(String newNombre){
		nombre = newNombre;
	}
	
	/**
	 * retorna el nombre del docente
	 * @return "string con el nombre"
	 */
	public String getNombre(){
		return nombre;
	}
	
	/**
	 * establece el apellido del docente
	 * @param newApellido "string con el apellido"
	 */
	public void setApellido(String newApellido){
		apellido = newApellido;
	}
	
	/**
	 * retorna el apellido del docente
	 * @return "string con el apellido"
	 */
	public String getApellido(){
		return apellido;
	}
	
	/**
	 * establece la direccion del docente
	 * @param newDireccion "string con la direccion"
	 */
	public void setDireccion(String newDireccion){
		direccion = newDireccion;
	}
	
	/**
	 * retorna la direccion del docente
	 * @return "string con la direccion"
	 */
	public String getDireccion(){
		return direccion;
	}
	
	/**
	 * establece el telefono del docente
	 * @param newTelefono "string con el telefono"
	 */
	public void setTelefono(String newTelefono){
		telefono = newTelefono;
	}
	
	/**
	 * retorna el numero de telefono del docente
	 * @return "string con el numero telefonico"
	 */
	public String getTelefono(){
		return telefono;
	}
	
	/**
	 * permite establece el email del docente
	 * @param newEmail "string con el email"
	 */
	public void setEmail(String newEmail){
		email = newEmail;
	}
	
	/**
	 * retorna el email del docente
	 * @return "string con el email"
	 */
	public String getEmail(){
		return email;
	}
	
	/**
	 * permite establece la fecha de nacimiento
	 * con formato yyyy-MM-dd
	 * @param newFecha_nac "string con la fecha de nacimiento"
	 */
	public void setFecha_nac(String newFecha_nac){
		fecha_nac = newFecha_nac;
	}
	
	/**
	 * retorna la fecha de nacmiento con
	 * formato yyyy-MM-dd
	 * @return "string con la fecha de nacimiento"
	 */
	public String getFecha_nac(){
		return fecha_nac;
	}
	
	/**
	 * permite establecer un valor a la edad	
	 * @param newEdad "int con la edad"
	 */
	public void setEdad(int newEdad){
		edad = newEdad;
	}
	
	/**
	 * retorna la edad del docente
	 * @return "int con la edad"
	 */
	public int getEdad(){
		return edad;
	}
	
	/**
	 * establece el sexo del docente
	 * un string 'male' or 'female'
	 * @param newSexo "string con el sexo"
	 */
	public void setSexo(String newSexo) {
		sexo= newSexo;
	}
	
	/**
	 * retorna el sexo del docente
	 * @return string "male" | "female"
	 */
	public String getSexo() {
		return sexo;
	}
	
	/**
	 * permie obtener el usuario asosiado a un docente
	 * @return "user del docente"
	 */
	public User getUser() {
		return user;
	}

	/**
	 * permite establecer el usuario del docente
	 * @param newUser "user del docente"
	 */
	public void setUser(User newUser) {
		user = newUser;
	}
	
	/**
	 * Funcion que permite guardar un docente en la base de datos
	 * @return logico con el resultado de la opreracion
	 */
	public boolean save() {
		try {
			Teacher.getTeacherByDni(dni);			
			return false;
		}
		catch (teacherNotFound e1) {
			String[] columns = { "dni", "nombre", "apellido", "username", "sexo", "direccion", "telefono", "email", "fecha_nac" };
			PreparedStatement stm = jpa.newRecord("docente", columns);
			try {
				stm.setString(1, dni);
				stm.setString(2, nombre);
				stm.setString(3, apellido);
				stm.setString(4, user.getUsername());
				stm.setString(5, sexo);
				stm.setString(6, direccion);
				stm.setString(7, telefono);
				stm.setString(8, email);
				stm.setString(9, fecha_nac);
			} catch (SQLException e) {
				e.printStackTrace();
				return false;
			}
			jpa.create(stm);
			return true;
		}
	}
	
	
	
	/**
	 * dado un teacher permite borrarlo de la base de datos
	 */
	public void destroy() {
		try {
			jpa.destroy("docente", "dni", getDni());
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * permite actualizar en la base de datos un docente
	 * @return true o false depende que onda
	 */
	public boolean update() {
		try {
			String[] datos = {dni,nombre,apellido,user.getUsername(),sexo,direccion,telefono,email,fecha_nac};
			String[] columns = { "dni", "nombre", "apellido", "username", "sexo", "direccion", "telefono", "email", "fecha_nac" };
			jpa.update("docente", columns, datos, "nro_docente", getNumero_docente());
			return true;
		} catch(Exception ex) {
			return false;
		}
	}


	/**
	 * Dado el nombre de usuario permite obtener el docente asosiado a �l
	 * @param username "nombre de usuario"
	 * @return Teacher "objeto del tipo teacher docente asosiado al usuario"
	 * @throws userNotFound "si el usuario no existe"
	 * @throws teacherNotFound "si el docente no existe"
	 */
	public static Teacher getTeacherByUsername(String username) throws teacherNotFound {
		ResultSet rs = null;
		Teacher t = null;
		rs = jpa.getByField("docente", "username", username);
		try {
			if (rs.next()) {
				t = new Teacher(rs.getString(1), rs.getString(2), rs.getString(3), rs.getString(4), User.getUserByUsername(rs.getString(5)), 
								      rs.getString(6), rs.getString(7), rs.getString(8), rs.getString(9), rs.getString(10));
			} else {
				throw new teacherNotFound();
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} catch (userNotFound e) {
			throw new teacherNotFound();
		}
		return t;
	}

	
	
	
	/**
	 * dado un dni (que pertenece a la base de datos) devuelve el objeto con todas las intancias que hace referencia al mismo
	 * @param dni
	 * @return Student
	 * @throws studentNotFound
	 * @throws NumberFormatException
	 * @throws userNotFound
	 */
	public static Teacher getTeacherByDni(String dni) throws teacherNotFound {
		ResultSet rs = null;
		Teacher t = null;		
		rs = jpa.getByField("docente", "dni", dni);
		try {
			if (rs.next()) {
				t = new Teacher(rs.getString(1), (rs.getString(2)), rs.getString(3), rs.getString(4), User.getUserByUsername(rs.getString(5)), 
						rs.getString(6),rs.getString(7), rs.getString(8), rs.getString(9), rs.getString(10));
			} else {
				throw new teacherNotFound();
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} catch (userNotFound e) {
			throw new teacherNotFound();
		}
		return t;
	}
	
	
	
	/**
	 * Funcion para ver todas las materias a las que pertenece el docente
	 * @return Array de Materias con las materias que es auxiliar o responsable
	 */
	public Materia[] getTeacherMaterias(){
		String[][] materiasE = jpa.ResultSetToStringArray(jpa.getByField("equipo", "cod_materia", "dni", getDni()));
		Materia[] result = new Materia[materiasE.length];
		for (int i=0;i<materiasE.length;i++) {
			try {
				result[i] =  Materia.getMateriaByCodigo(materiasE[i][0]);
			} catch (NumberFormatException e) {
				e.printStackTrace();
			} catch (materiaNotFound e) {
				e.printStackTrace();
			}			
		}
		return result;		
	}
	
	
	/**
	 * Obtiene la tabla docentes de la base de datos
	 * @return matriz Object con los datos
	 */
	public static Object[][] getTeacherTable(){
		Object[][] teacherTable = jpa.ResultSetToArray(jpa.showAll("docente"));
		return teacherTable;
	}
	
	
	/**
	 * Obtiene la lista de docentes disponibles
	 * @return Array de Teachers
	 */
	public static Teacher[] getTeacherList() {
		String[][] result = jpa.ResultSetToStringArray(jpa.showProyection("docente", "dni"));
		Teacher[] teacherList = new Teacher[result.length];
		for (int i=0;i<result.length;i++) {
			try {
				teacherList[i] = Teacher.getTeacherByDni(result[i][0]);
			} catch (NumberFormatException e1) {
				e1.printStackTrace();
			} catch (teacherNotFound e1) {
				e1.printStackTrace();
			}
		}
		return teacherList;
	}
		
	
	/**
	 * Obtiene todos los docentes que no son 
	 * responsables de alguna materia
	 * @return Teacher[]  arreglo de docentes
	 */
	public static Teacher[] getTeacherListNotInMateria() {
		String[][] result = jpa.ResultSetToStringArray(jpa.showNotIn("docente","dni","dni","materia","dni"));
		Teacher[] teacherList = new Teacher[result.length];
		for (int i=0;i<result.length;i++) {
			try {
				teacherList[i] = Teacher.getTeacherByDni(result[i][0]);
			} catch (NumberFormatException e) {
				e.printStackTrace();
			} catch (teacherNotFound e) {
				e.printStackTrace();
			}
		}
		return teacherList;
	}
	
	
	
	/**
	 * Compara objetos del tipo teacher	
	 */
	public boolean equals(Object arg0) {
		if (arg0==null) {
			return false;
		}
		if (this.getDni().equals(((Teacher) arg0).getDni())) {
			return true;
		}
		return false;		
	}
	
	/**
	 * Funcion que calcula la edad actual a partir de la fecha de nacmiento
	 * @param fecha_nac "fecha de nacimiento en string yyyy-MM-dd"
	 * @return int "edad calculada al dia de hou"
	 */
	public static int edad(String fecha_nac) {		   
	    Date fechaActual = new Date();
	    SimpleDateFormat formato = new SimpleDateFormat("yyyy-MM-dd");
	    String hoy = formato.format(fechaActual);
	    String[] dat1 = fecha_nac.split("-");
	    String[] dat2 = hoy.split("-");
	    int anos = Integer.parseInt(dat2[0]) - Integer.parseInt(dat1[0]);
	    int mes = Integer.parseInt(dat2[1]) - Integer.parseInt(dat1[1]);
	    if (mes < 0) {
	      anos = anos - 1;
	    } else if (mes == 0) {
	      int dia = Integer.parseInt(dat2[2]) - Integer.parseInt(dat1[2]);
	      if (dia > 0) {
	        anos = anos - 1;
	      }
	    }
	    return anos;
	}

	/**
	 * Redefinicion del metodo toString para la clase
	 */
	public String toString() {
		return this.getDni()+" -- "+this.getApellido()+", "+this.getNombre();				
	}
	
	
	/**
	 * Metodo utilizado en la busqueda
	 * @param arg0 string a buscar
	 * @return boolean si es parecido o no
	 */
	public boolean comparar(String arg0) {
		String busq = arg0.toLowerCase();
		String ape = this.getApellido().toLowerCase();
		String nam = this.getNombre().toLowerCase();
		String dni = this.getDni().toLowerCase();
		return (busq.equals(ape) || busq.equals(nam) || busq.equals(dni));
	}
}
